package com.ruoyi.project.purchase.service.impl;

import java.util.Date;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.domain.ResultBean;
import com.ruoyi.project.purchase.domain.*;
import com.ruoyi.project.purchase.domain.pojo.DepotDetailBean;
import com.ruoyi.project.purchase.domain.pojo.DepotHeadItem;
import com.ruoyi.project.purchase.mapper.RyDepotDetailMapper;
import com.ruoyi.project.purchase.mapper.RyDepotHeadMapper;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.warehouse.domain.OutRyDepotItem;
import com.ruoyi.project.warehouse.domain.RyDepotItem;
import com.ruoyi.project.warehouse.domain.RyInventoryCurrentStock;
import com.ruoyi.project.warehouse.mapper.OutRyDepotItemMapper;
import com.ruoyi.project.warehouse.mapper.RyDepotItemMapper;
import com.ruoyi.project.warehouse.mapper.RyDepotMapper;
import com.ruoyi.project.warehouse.mapper.RyInventoryCurrentStockMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.purchase.mapper.ProjectClearanceMapper;
import com.ruoyi.project.purchase.service.IProjectClearanceService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 项目清仓Service业务层处理
 *
 * @author you
 * @date 2022-09-27
 */
@Service
public class ProjectClearanceServiceImpl implements IProjectClearanceService
{
    @Autowired
    private ProjectClearanceMapper projectClearanceMapper;

    @Autowired
    private RyDepotDetailMapper ryDepotDetailMapper;

    @Autowired
    private RyDepotItemMapper ryDepotItemMapper;

    @Autowired
    private OutRyDepotItemMapper outRyDepotItemMapper;

    @Autowired
    private RyInventoryCurrentStockMapper ryInventoryCurrentStockMapper;

    @Autowired
    private RyDepotHeadMapper ryDepotHeadMapper;

    /**
     * 查询项目清仓
     *
     * @param id 项目清仓主键
     * @return 项目清仓
     */
    @Override
    public ProjectClearance selectProjectClearanceById(Long id)
    {
        return projectClearanceMapper.selectProjectClearanceById(id);
    }

    /**
     * 查询项目清仓列表
     *
     * @param projectClearance 项目清仓
     * @return 项目清仓
     */
    @Override
    public List<ProjectClearance> selectProjectClearanceList(ProjectClearance projectClearance)
    {
        return projectClearanceMapper.selectProjectClearanceList(projectClearance);
    }

    /**
     * 查询单据主表及子表信息
     *
     * @param id 单据主表主键
     * @return 单据主表及子表信息
     */
    public DepotHeadItem selectRyDepotDetailByDepotId(Long id){


        DepotHeadItem depotHeadItem = new DepotHeadItem();
        RyDepotHead ryDepotHead = ryDepotHeadMapper.selectRyDepotHeadById(id);
        //主表数据
        depotHeadItem.setId(ryDepotHead.getId());
        depotHeadItem.setProjectCode(ryDepotHead.getProjectCode());
        depotHeadItem.setProjectName(ryDepotHead.getProjectName());
        depotHeadItem.setDepotId(ryDepotHead.getDepotId());
        depotHeadItem.setProjectStatus(ryDepotHead.getProjectStatus());
        depotHeadItem.setNumber(ryDepotHead.getNumber());
        depotHeadItem.setContractNumber(ryDepotHead.getContractNumber());
        depotHeadItem.setCreator(ryDepotHead.getCreator());
        depotHeadItem.setOperTime(ryDepotHead.getOperTime());
        depotHeadItem.setFileName(ryDepotHead.getFileName());
        depotHeadItem.setSalesMan(ryDepotHead.getSalesMan());
        depotHeadItem.setCreateTime(ryDepotHead.getCreateTime());
        depotHeadItem.setRemark(ryDepotHead.getRemark());
        //子表数据
        List<RyDepotItem> tableData = ryDepotItemMapper.selectAllDetailByDepotId(id);
        depotHeadItem.setTableData(tableData);
        return depotHeadItem;
    }

    /**
     * 仓库剩余数量转移
     * 1.项目库出库
     * 2.总库入库
     * 3.生成相应出入库记录
     * 4.修改项目库出库数量
     */
    @Transactional
    @Override
    public AjaxResult editProjectClearance(DepotHeadItem depotHeadItem){
        //获取用户信息
        SysUser user = SecurityUtils.getLoginUser().getUser();

        //判断是否有子表数据
        List<RyDepotItem> tableData = depotHeadItem.getTableData();
        if(tableData == null || tableData.size() ==0){
            return AjaxResult.error("子表数据不存在");
        }

        //主表（项目总清单）只需要修改个别信息即可
        ProjectClearance projectClearance = new ProjectClearance();
        projectClearance.setId(depotHeadItem.getId());//主键，用于定位修改数据

        projectClearance.setClearTime(DateUtils.getNowDate());//清仓时间
        projectClearance.setFileName(depotHeadItem.getFileName());
        projectClearance.setRemark(depotHeadItem.getRemark());

        //修改
        projectClearanceMapper.updateProjectClearance(projectClearance);

        /**
         * 1.新增项目清仓出库单主表数据，用于记录项目清仓时物品出库信息
         * 2.新增项目清单入库单主表护具，用于记录项目清仓总库入库信息
         * 3.循环明细数据，关联主表信息
         */
        //1.新增项目清仓出库单主表信息
        RyDepotHead clearOutMain = new RyDepotHead();
        clearOutMain.setNumber(depotHeadItem.getNumber().replace("WBSP","XMQCCK"));
        clearOutMain.setCreateTime(DateUtils.getNowDate());
        clearOutMain.setCreator(user.getUserId());
        clearOutMain.setStatus("0");
        clearOutMain.setType("出库");
        clearOutMain.setSubType("项目清仓");
        clearOutMain.setProjectHeadId(depotHeadItem.getId());//关联项目总清单
        ryDepotHeadMapper.insertRyDepotHead(clearOutMain);

        //2.新增项目清仓入库单主表信息
        RyDepotHead clearInMain = new RyDepotHead();
        clearInMain.setNumber(depotHeadItem.getNumber().replace("WBSP","XMQCRK"));
        clearInMain.setCreateTime(DateUtils.getNowDate());
        clearInMain.setCreator(user.getUserId());
        clearInMain.setStatus("0");
        clearInMain.setType("入库");
        clearInMain.setSubType("项目清仓");
        clearInMain.setProjectHeadId(depotHeadItem.getId());//关联项目总清单
        ryDepotHeadMapper.insertRyDepotHead(clearInMain);

        /**
         * 统计参数，用于统计明细清仓数量
         * 如果totalInNum > 0 存在清仓明细，则不需处理
         * 如果totalInNum <= 0 说明明细数据因为条件问题一条都没有清仓，
         * 这时就主动抛出错误，使得事务生效，防止主表信息插入而明细表没有数据
         *
         */
        int totalInNum = 0;

        //遍历清仓数据
        for(RyDepotItem ryDepotItem : tableData){
            //如果总入库数量为0或是为null,或是操作数量operNumber为0或者为null，则跳过此次循环，不进行出库操作
            if(ryDepotItem.getHavaInNum() == null || ryDepotItem.getHavaInNum() == 0 || ryDepotItem.getOperNumber() == null || ryDepotItem.getOperNumber() == 0){
                continue;
            }

            //(总入库-总出库) < 操作数量，则跳过
            // if((ryDepotDetail.getInNum() - ryDepotDetail.getOutNum()) < ryDepotDetail.getOperNumber()){
            //     continue;
            // }

            try {
                /**
                 * 1.处理项目库出库相关逻辑
                 */
                projectOut(clearOutMain, ryDepotItem, depotHeadItem.getDepotId());

                /**
                 * 2.处理总仓库相关逻辑
                 */
                totalDepotIn(clearInMain,ryDepotItem,1L);

            }catch(Exception e){
                throw e;
            }

            totalInNum += 1;
        }

        //如果统计结果小于等于0,则主动抛出异常
        if(totalInNum <= 0){
            System.out.println("应主动抛出异常,稍后完善");
        }

        return AjaxResult.success("操作成功");
    }

    /**
     * 处理总仓库入库相关逻辑
     */
    public void totalDepotIn(RyDepotHead clearInMain,RyDepotItem ryDepotItem,Long depotId){
        ryDepotItem.setHeaderId(clearInMain.getId());//设置刚生成的入库单id
        ryDepotItem.setHeaderType("0");//0代表入库数据
        ryDepotItem.setOperTime(new Date());
        ryDepotItem.setDepotId(depotId);//设置入库仓库

        //获取仓库id和商品id
//        Long depotId = 1L;//总仓库id为1
        Long inventoryId = ryDepotItem.getInventoryId();
        RyInventoryCurrentStock paramstock = new RyInventoryCurrentStock();
        paramstock.setDepotId(depotId);
        paramstock.setInventoryId(inventoryId);
        //根据depotId和InventoryId查询出当前总仓库库存信息(总仓库)
        RyInventoryCurrentStock result = ryInventoryCurrentStockMapper.getCurrentStockByDepotInventId(paramstock);
        System.out.println("--> result:"+result);

        //创建参数对象
        RyInventoryCurrentStock param = new RyInventoryCurrentStock();
        if(result != null){//存在此数据，执行修改
            //计算需要更改的数量
            //获取原库存数
            Double oldNum = result.getCurrentNumber();
            //获取新入库数量
            Double inNum = ryDepotItem.getOperNumber();
            //需要更改的数量
            Double updateNum = oldNum + inNum;
            param.setCurrentNumber(updateNum);

            //执行修改语句，根据id修改
            param.setId(result.getId());
            ryInventoryCurrentStockMapper.updateRyInventoryCurrentStock(param);

        } else {//不存在,执行新增
            param.setDepotId(depotId);
            param.setInventoryId(inventoryId);
            param.setCurrentNumber(ryDepotItem.getOperNumber());

            //执行新增语句
            ryInventoryCurrentStockMapper.insertRyInventoryCurrentStock(param);
        }

        //执行明细新增
        ryDepotItemMapper.insertRyDepotItem(ryDepotItem);
    }

    /**
     * 处理项目库出库相关逻辑
     */
    public void projectOut(RyDepotHead clearOutMain,RyDepotItem ryDepotItem,Long depotId){

        ryDepotItem.setHeaderId(clearOutMain.getId());//设置刚生成的出库单id
        ryDepotItem.setHeaderType("1");//1代表出库数据
        ryDepotItem.setOperTime(new Date());
        ryDepotItem.setDepotId(depotId);

        //1.获取项目库id和商品id
//        Long depotId = depotHeadItem.getDepotId();
        Long inventoryId = ryDepotItem.getInventoryId();
        RyInventoryCurrentStock paramstock = new RyInventoryCurrentStock();
        paramstock.setDepotId(depotId);
        paramstock.setInventoryId(inventoryId);
        //根据depotId和InventoryId查询出当前项目库存信息(项目库)
        RyInventoryCurrentStock result = ryInventoryCurrentStockMapper.getCurrentStockByDepotInventId(paramstock);
        System.out.println("--> 项目库库存:"+result);
        //创建参数对象
        RyInventoryCurrentStock param = new RyInventoryCurrentStock();
        //计算需要更改的总库数量
        //获取原库存数
        Double oldNum = result.getCurrentNumber();
        //获取新出库数量
        Double outNum = ryDepotItem.getOperNumber();
        //需要更改的数量
        Double updateNum = oldNum - outNum;
        param.setCurrentNumber(updateNum);

        //执行修改语句，修改库存数量，根据id修改
        param.setId(result.getId());
        ryInventoryCurrentStockMapper.updateRyInventoryCurrentStock(param);

        //执行明细新增
        ryDepotItemMapper.insertRyDepotItem(ryDepotItem);
    }

    /**
     * 新增项目清仓
     *
     * @param projectClearance 项目清仓
     * @return 结果
     */
    @Override
    public int insertProjectClearance(ProjectClearance projectClearance)
    {
        projectClearance.setCreateTime(DateUtils.getNowDate());
        return projectClearanceMapper.insertProjectClearance(projectClearance);
    }

    /**
     * 修改项目清仓
     *
     * @param projectClearance 项目清仓
     * @return 结果
     */
    @Override
    public int updateProjectClearance(ProjectClearance projectClearance)
    {
        return projectClearanceMapper.updateProjectClearance(projectClearance);
    }

    /**
     * 批量删除项目清仓
     *
     * @param ids 需要删除的项目清仓主键
     * @return 结果
     */
    @Override
    public int deleteProjectClearanceByIds(Long[] ids)
    {
        return projectClearanceMapper.deleteProjectClearanceByIds(ids);
    }

    /**
     * 删除项目清仓信息
     *
     * @param id 项目清仓主键
     * @return 结果
     */
    @Override
    public int deleteProjectClearanceById(Long id)
    {
        return projectClearanceMapper.deleteProjectClearanceById(id);
    }
}
